home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 11 - 1995 / 11.02 Feb 95 / Yenta / Erics C++ Libraries / Interface Classes / CPPWindow.cp < prev    next >
Encoding:
Text File  |  1996-04-04  |  23.1 KB  |  859 lines  |  [TEXT/KAHL]

  1. /***************************************************** IMPLEMENTATION
  2.     DATE:    9/20/93
  3.     AUTHOR: Eric R. Rosé
  4.  
  5.     CLASS:  CPPWindow
  6.     
  7.     SUPERCLASS: CPPObjectList
  8.     
  9.         This C++ class manages a Macintosh window; it is subclassed
  10.         from an object list so that it can keep track of all of the
  11.         objects within the window
  12.     
  13. ********************************************************************/
  14.  
  15. #include <CPPWindow.h>
  16. #include <math.h>
  17. #include <MathTools.h>
  18. #include <CPPWindowManager.h>
  19. #include <CPPVisualObject.h>
  20. #include <Commands.h>
  21.  
  22.  
  23. /*-----------------------------------------------------------------*/
  24. /*--------------------------- GLOBALS -----------------------------*/
  25. /*-----------------------------------------------------------------*/
  26.  
  27.     CPPWindow    *gTheModalWindow;
  28.     pascal Boolean ModalFilterProc (DialogPtr theDlg,
  29.                                     EventRecord *theEvent,
  30.                                     short *itemHit );
  31.     void DoStdOKButton (CPPWindow *theWindow);
  32.     void DoStdCancelButton (CPPWindow *theWindow);
  33.  
  34. /*-----------------------------------------------------------------*/
  35. /*------------------------ PUBLIC METHODS -------------------------*/
  36. /*-----------------------------------------------------------------*/
  37.  
  38.     void DoStdCancelButton (CPPWindow *theWindow)
  39.     {
  40.         if (theWindow)
  41.           theWindow->EndModalWindow (FALSE);
  42.     }
  43.  
  44. /*-----------------------------------------------------------------*/
  45.  
  46.     void DoStdOKButton (CPPWindow *theWindow)
  47.     {
  48.         if (theWindow)
  49.           theWindow->EndModalWindow (TRUE);
  50.     }
  51.  
  52. /*-----------------------------------------------------------------*/
  53.  
  54.     CPPWindow::CPPWindow (CPPWindowManager *theManager,
  55.                           Rect *bounds, Str255 title, Boolean isVisible,
  56.                           short windowKind, Boolean hasGoAway, short refCon,
  57.                           Boolean isModal, Boolean isColor, 
  58.                           short windowFont, short windowSize)
  59.     /* create a window based on the passed in parameters */
  60.     {
  61.         if (isColor)
  62.           this->theWindow = NewCWindow(NULL, bounds, title, isVisible, 
  63.                                         windowKind, (WindowPtr)-1,
  64.                                         hasGoAway, refCon);
  65.         else
  66.           this->theWindow = NewWindow(NULL, bounds, title, isVisible, 
  67.                                         windowKind, (WindowPtr)-1,
  68.                                         hasGoAway, refCon);
  69.           
  70.         if (this->theWindow)
  71.           MakeCPPWindow (theManager, windowFont, windowSize);
  72.         else
  73.           this->WisVisible = this->WisActive = FALSE;
  74.         
  75.         this->isCWindow = isColor;
  76.         this->isModalWindow = isModal;
  77.         this->modalResult = FALSE;
  78.     }
  79.     
  80. /*-----------------------------------------------------------------*/
  81.  
  82.     CPPWindow::CPPWindow (CPPWindowManager *theManager, short ResID,
  83.                           Boolean isModal, Boolean isColor, 
  84.                           short windowFont, short windowSize)
  85.     /* get a window based on an existing resource template */
  86.     {
  87.         
  88.           if (isColor)
  89.             this->theWindow = GetNewCWindow(ResID, NULL, (WindowPtr)-1);
  90.         else
  91.             this->theWindow = GetNewWindow(ResID, NULL, (WindowPtr)-1);
  92.           
  93.           if (this->theWindow)
  94.             MakeCPPWindow (theManager, windowFont, windowSize);
  95.         else
  96.           this->WisVisible = this->WisActive = FALSE;
  97.           
  98.         this->isCWindow = isColor;
  99.         this->isModalWindow = isModal;
  100.     }
  101.     
  102. /*-----------------------------------------------------------------*/
  103.     
  104.     CPPWindow::~CPPWindow (void)
  105.     {
  106.         CPPVisualObject    *TempObject = NULL;
  107.  
  108.         // first, hide our window; this will take care of
  109.         // updates in the window list
  110.         this->Close();
  111.         
  112.         // tell the windowmanager it doesn't have to worry about us
  113.         if (this->ourManager)
  114.           this->ourManager->StopManagingWindow(this);
  115.         
  116.         // dispose of all the objects which we contain
  117.         DeleteItems(TRUE);
  118.         
  119.         // finally, dispose of our own data
  120.         if (this->theWindow)
  121.           DisposeWindow(this->theWindow);
  122.     }
  123.             
  124. /*-----------------------------------------------------------------*/
  125.  
  126.     void    CPPWindow::Close (void)
  127.     /* perform a close operation by simply hiding the window */
  128.     {
  129.         if (this->theWindow && ((WindowPeek)this->theWindow)->goAwayFlag)
  130.           this->Show(FALSE);
  131.     }
  132.  
  133. /*-----------------------------------------------------------------*/
  134.  
  135.     void    CPPWindow::Open (void)
  136.     /* perform a close operation by simply showing a hidden window */
  137.     {
  138.         this->Show(TRUE);
  139.     }
  140.  
  141. /*-----------------------------------------------------------------*/
  142.  
  143.     char    *CPPWindow::ClassName (void)
  144.     {
  145.         return "CPPWindow";
  146.     }
  147.             
  148. /*-----------------------------------------------------------------*/
  149.  
  150.     void    CPPWindow::EndModalWindow (Boolean endResult)
  151.     /* tell the modal window to dismiss itself; return the specified */
  152.     /* value as a result */
  153.     {
  154.         this->modalResult = endResult;
  155.         this->modalDone = TRUE;
  156.     }
  157.  
  158. /*-----------------------------------------------------------------*/
  159.  
  160.     void    CPPWindow::DoModalWindow (void)
  161.     /* treat the window as if it were a modal window */
  162.     {
  163.         EventRecord        theEvent;
  164.         CPPWindow        *theWindowObject;
  165.         short            eventMask;
  166.     
  167.         // assume the user will cancel
  168.         this->modalResult = FALSE;
  169.         
  170.         // set up the event mask to only accept modal dialog events
  171.         eventMask = mDownMask + mUpMask + keyDownMask + keyUpMask +
  172.                     autoKeyMask + updateMask + activMask + networkMask;
  173.         
  174.           // set the modal window completion variable
  175.           this->modalDone = FALSE;
  176.  
  177.         while (!this->modalDone)
  178.           {
  179.               if (WaitNextEvent(eventMask, &theEvent, 0, NULL))
  180.               this->Do(&theEvent);
  181.             else    
  182.               this->DoIdle();
  183.           }
  184.     }
  185.  
  186. /*-----------------------------------------------------------------*/
  187.  
  188.     void    CPPWindow::SetMinMaxSize (short minWidth, short minHeight,
  189.                                        short maxWidth, short maxHeight)
  190.     {
  191.         this->minWidth = minWidth;
  192.         this->minHeight = minHeight;
  193.         this->maxWidth = maxWidth;
  194.         this->maxHeight = maxHeight;
  195.         
  196.         // let the window manager maintain the data it needs
  197.         // for zoomable windows;
  198.           switch (GetWVariant(this->theWindow)) {
  199.               case zoomNoGrow :
  200.               case zoomDocProc :
  201.                 SetZoomedOutSize (maxWidth, maxHeight);
  202.                   break;
  203.           }
  204.     }
  205.  
  206. /*-----------------------------------------------------------------*/
  207.  
  208.     void    CPPWindow::SetZoomedOutSize (short maxWidth, short maxHeight)
  209.     {
  210.         WStateData    **hWSD;
  211.         Rect        zRect;
  212.         
  213.         // set the 'zoomed out' size of the window to the maximum size
  214.         if (theWindow)
  215.           {
  216.               hWSD = (WStateData **)((WindowPeek)theWindow)->dataHandle;
  217.               zRect = (**hWSD).stdState;
  218.               zRect.bottom = Min (zRect.top + maxHeight, zRect.bottom);
  219.               zRect.right = Min (zRect.left + maxWidth, zRect.right);
  220.               (**hWSD).stdState = zRect;
  221.               this->maxWidth = (zRect.right - zRect.left);
  222.               this->maxHeight = (zRect.bottom - zRect.top);
  223.           }
  224.     }
  225.  
  226. /*-----------------------------------------------------------------*/
  227.  
  228.     Boolean    CPPWindow::DoCommand (short commandID)
  229.     /* the default method sends the command to the target of the */
  230.     /* window. */
  231.     /* SUBCLASS SHOULD OVERRIDE */
  232.     {
  233.         CPPVisualObject *theTarget = GetTarget();
  234.         
  235.         if (theTarget)
  236.           return theTarget->DoCommand(commandID);
  237.         else
  238.           return FALSE;
  239.     }
  240.  
  241. /*-----------------------------------------------------------------*/
  242.  
  243.     WindowPtr    CPPWindow::GetWindow (void)
  244.     {
  245.         return this->theWindow;
  246.     }
  247.  
  248. /*-----------------------------------------------------------------*/
  249.  
  250.     void    CPPWindow::Update (EventRecord *theEvent)
  251.     {
  252.         WindowPtr    uWindow = (WindowPtr)theEvent->message;
  253.         GrafPtr        savePort;
  254.         
  255.         if (uWindow == this->theWindow)
  256.           {
  257.               // prepare the window to be drawn into
  258.               BeginUpdate (this->theWindow);
  259.               GetPort (&savePort);
  260.               SetPort (this->theWindow);
  261.               
  262.               // call the user's draw routine
  263.               this->DoUserUpdate();
  264.               
  265.               // draw the grow icon if necessary
  266.               switch (GetWVariant(this->theWindow)) {
  267.                   case documentProc :
  268.                   case zoomDocProc :
  269.                       DrawGrowIcon(this->theWindow);
  270.                       break;
  271.               }
  272.               
  273.               // restore the drawing environment
  274.               SetPort (savePort);
  275.               EndUpdate (this->theWindow);
  276.           }
  277.     }
  278.     
  279. /*-----------------------------------------------------------------*/
  280.  
  281.     void    CPPWindow::Show (Boolean doShowWindow)
  282.     /* make the window visible or invisible */
  283.     {
  284.         if (this->theWindow)
  285.           {
  286.             if (doShowWindow)
  287.               {
  288.                 ShowWindow (this->theWindow);
  289.                 SelectWindow (this->theWindow);
  290.                 this->ourManager->ActivateWindowObject (this);
  291.               }
  292.             else
  293.               {
  294.                   HideWindow(this->theWindow);
  295.                 this->ourManager->DeactivateWindowObject (this);
  296.                 }
  297.             
  298.             this->WisVisible = doShowWindow;
  299.           }
  300.     }
  301.             
  302. /*-----------------------------------------------------------------*/
  303.  
  304.     void    CPPWindow::RefreshItemStates()
  305.     /* this routine is called whenever an event occurs so that */
  306.     /* the window can check to see if any of the objects in it */
  307.     /* should be enabled/disabled, etc.  For example, if a button */
  308.     /* should only be active when certain conditions are true, */
  309.     /* you could use this routine to activate/deactivate it */
  310.     /* SUBCLASS SHOULD OVERRIDE */
  311.     {
  312.     
  313.     }
  314.  
  315. /*-----------------------------------------------------------------*/
  316.  
  317.     Boolean    CPPWindow::Do (EventRecord *theEvent)
  318.     /* handle the passed event; return TRUE if you handle it, */
  319.     /* FALSE if you dont */
  320.     {
  321.         GrafPtr    savePort;
  322.         Boolean    result = FALSE;
  323.         WindowPtr    EventWindow;
  324.                 
  325.         if (!theWindow) return FALSE;
  326.         
  327.         // check to see if the event happened in our window
  328.         switch (theEvent->what) {
  329.             case updateEvt :
  330.             case activateEvt :
  331.                 EventWindow = (WindowPtr)theEvent->message;
  332.                 break;
  333.             case keyDown :
  334.             case autoKey :
  335.                 EventWindow = FrontWindow();
  336.                 break;
  337.             default :
  338.                 FindWindow (theEvent->where, &EventWindow);
  339.                 break;
  340.         } 
  341.         
  342.         if (this->theWindow != EventWindow)
  343.           return FALSE;
  344.         
  345.         // now that we know the event happened in our window,
  346.         // handle it
  347.         GetPort(&savePort);
  348.         SetPort(this->theWindow);
  349.     
  350.         switch (theEvent->what) {
  351.             case nullEvent : 
  352.                 if (this->WisActive)
  353.                     {
  354.                       DoUserIdle ();
  355.                       result = TRUE;
  356.                     }
  357.                   break;
  358.             case mouseDown :
  359.                 result = this->DoClick(theEvent);
  360.                 break;
  361.             case keyDown :
  362.             case autoKey :
  363.                 result = this->DoUserKey (theEvent);
  364.                 break;
  365.             case updateEvt:
  366.                 this->Update(theEvent);
  367.                 result = TRUE;
  368.                 break;
  369.             case activateEvt :
  370.                 if (ODD(theEvent->modifiers))
  371.                   this->ourManager->ActivateWindowObject(this);
  372.                 else
  373.                   this->ourManager->DeactivateWindowObject(this);
  374.                 result = TRUE;
  375.                 break;
  376.         }
  377.         
  378.         RefreshItemStates();
  379.         
  380.         SetPort(savePort);
  381.         return result;
  382.     }
  383.  
  384. /*-----------------------------------------------------------------*/
  385.  
  386.     Boolean    CPPWindow::DoClick (EventRecord *theEvent)
  387.     /* react to a click in the object's window by bringing it */
  388.     /* forward (if necessary) and performing the appropriate action */
  389.     /* return TRUE if the click was in our window, FALSE otherwise */
  390.     {
  391.         short    part;
  392.         WindowPtr    hitWindow;
  393.  
  394.         part = FindWindow(theEvent->where, &hitWindow);
  395.         if (hitWindow == this->theWindow)
  396.           {
  397.               if (!this->WisActive)
  398.                 SelectWindow(this->theWindow);
  399.  
  400.               switch (part) {
  401.                   case inDrag     :
  402.                       DoDragClick (theEvent);
  403.                       break;
  404.                   case inGrow        :
  405.                       DoGrowClick (theEvent);
  406.                       break;
  407.                   case inZoomIn    :
  408.                       DoZoomClick (theEvent, part);
  409.                       break;
  410.                   case inZoomOut    :
  411.                       DoZoomClick (theEvent, part);
  412.                       break;
  413.                   case inGoAway    :
  414.                     DoGoAwayClick (theEvent);
  415.                     break;
  416.                   case inContent    :
  417.                     DoContentClick (theEvent);
  418.                     break;
  419.                 default :
  420.                     return FALSE;
  421.                     break;
  422.               }
  423.               return TRUE;
  424.           }
  425.           
  426.         return FALSE;
  427.     }
  428.  
  429. /*-----------------------------------------------------------------*/
  430.  
  431.     void    CPPWindow::DoIdle (void)
  432.     {
  433.         DoUserIdle ();
  434.     }
  435.  
  436. /*-----------------------------------------------------------------*/
  437.  
  438.     Boolean    CPPWindow::MakePreviousTarget (void)
  439.     /* make the 'targetable' and visible object preceeding the */
  440.     /* current one into the target for the window; return TRUE if */
  441.     /* the target changes */
  442.     {
  443.         CPPVisualObject    *oldTarget = this->currentTarget, 
  444.                         *newTarget = NULL,
  445.                         *tempObject = NULL;
  446.         long            itemsToCheck = GetNumItems(),
  447.                         itemsInList = itemsToCheck,
  448.                         current = FindIndex(currentTarget);
  449.         
  450.         // proceed through the list from the current element,
  451.         // looking for the next one which can be made the target            
  452.         while (itemsToCheck)
  453.           {
  454.               current--;
  455.               if (!current)
  456.                 current = itemsInList;
  457.               tempObject = (CPPVisualObject *)((*this)[current]);
  458.               if (tempObject && tempObject->IsVisible() && 
  459.                   tempObject->CanBeMadeTarget())
  460.                 {
  461.                     newTarget = tempObject;
  462.                     break;
  463.                 }
  464.               itemsToCheck--;
  465.           }
  466.         
  467.         // if there is another object targetable, target it
  468.         if ((newTarget) && (newTarget != oldTarget))
  469.           {
  470.             MakeTarget(newTarget);
  471.             return TRUE;
  472.           }
  473.         else
  474.           return FALSE;
  475.     }
  476.  
  477. /*-----------------------------------------------------------------*/
  478.  
  479.     Boolean    CPPWindow::MakeNextTarget ()
  480.     /* make the next 'targetable' and visible object into the target */
  481.     /* for the window; return TRUE if the target changed */
  482.     {
  483.         CPPVisualObject    *oldTarget = this->currentTarget, 
  484.                         *newTarget = NULL,
  485.                         *tempObject = NULL;
  486.         long            itemsToCheck = GetNumItems(),
  487.                         itemsInList = itemsToCheck,
  488.                         current = FindIndex(currentTarget);
  489.         
  490.         // proceed through the list from the current element,
  491.         // looking for the next one which can be made the target            
  492.         while (itemsToCheck)
  493.           {
  494.               current = ((current + 1) % (itemsInList+1));
  495.               current += (current) ? 0 : 1;
  496.               tempObject = (CPPVisualObject *)((*this)[current]);
  497.               if (tempObject && tempObject->IsVisible() && 
  498.                   tempObject->CanBeMadeTarget())
  499.                 {
  500.                     newTarget = tempObject;
  501.                     break;
  502.                 }
  503.               itemsToCheck--;
  504.           }
  505.         
  506.         // if there is another object targetable, target it
  507.         if ((newTarget) && (newTarget != oldTarget))
  508.           {
  509.             MakeTarget(newTarget);
  510.             return TRUE;
  511.           }
  512.         else
  513.           return FALSE;
  514.     }
  515.  
  516. /*-----------------------------------------------------------------*/
  517.  
  518.     CPPVisualObject     *CPPWindow::GetTarget (void)
  519.     /* return the current target in the window */
  520.     {
  521.         return this->currentTarget;
  522.     }
  523.  
  524. /*-----------------------------------------------------------------*/
  525.  
  526.     void    CPPWindow::MakeTarget (CPPVisualObject *theObject)
  527.     /* The target is the object which should receive key events. */
  528.     /* call this routine to change the target object in the window */
  529.     /* if 'theObject' = NULL, assume the user wants to deactivate */
  530.     /* the current target without assigning another */
  531.     {
  532.         if (theObject == NULL)
  533.           {
  534.               if (this->currentTarget)
  535.                 this->currentTarget->TargetHilite(FALSE);
  536.               this->currentTarget = NULL;
  537.           }
  538.         else
  539.         if (FindIndex(theObject))
  540.           {
  541.               if ((theObject != this->currentTarget) && 
  542.                   theObject->CanBeMadeTarget() && theObject->IsVisible())
  543.                 {
  544.                 if (this->currentTarget)
  545.                   this->currentTarget->TargetHilite (FALSE);
  546.                 this->currentTarget = theObject;
  547.                 this->currentTarget->TargetHilite (TRUE);
  548.                 }
  549.           }
  550.     }
  551.  
  552. /*-----------------------------------------------------------------*/
  553.  
  554.     Boolean CPPWindow::IsColorWindow (void)
  555.     /* return TRUE if this is a color window */
  556.     {
  557.         return this->isCWindow;
  558.     }
  559.  
  560. /*-----------------------------------------------------------------*/
  561.  
  562.     Boolean CPPWindow::IsModalWindow (void)
  563.     /* return TRUE if this is a modal or movable modal window */
  564.     {
  565.         return this->isModalWindow;
  566.     }
  567.  
  568. /*-----------------------------------------------------------------*/
  569.  
  570.     Boolean    CPPWindow::WindowVisible (void)
  571.     /* return whether or not the window is visible */
  572.     {
  573.         return this->WisVisible;
  574.     }
  575.  
  576. /*-----------------------------------------------------------------*/
  577.  
  578.     Boolean    CPPWindow::WindowActive (void)
  579.     /* return whether or not the window is active */
  580.     {
  581.         return this->WisActive;
  582.     }
  583.  
  584. /*-----------------------------------------------------------------*/
  585.  
  586.     void    CPPWindow::StartManagingObject (CPPVisualObject *theObject)
  587.     /* add a visual object to the list of objects we know about */
  588.     {
  589.         if (theObject)
  590.           this->AppendItem (theObject);
  591.     }
  592.  
  593. /*-----------------------------------------------------------------*/
  594.  
  595.     void    CPPWindow::StopManagingObject (CPPVisualObject *theObject)
  596.     /* remove a visual object from the list of objects we know about */
  597.     {
  598.         DeleteItem(theObject, FALSE);
  599.     }
  600.  
  601. /*-----------------------------------------------------------------*/
  602. /*---------------------- PROTECTED METHODS ------------------------*/
  603. /*-----------------------------------------------------------------*/
  604.  
  605.     pascal Boolean ModalFilterProc (DialogPtr theDlg,
  606.                                     EventRecord *theEvent,
  607.                                     short *itemHit)
  608.     /* this class method is used as the modal dialog filter; it */
  609.     /* passes the event it receives on to the window object stored */
  610.     /* in gTheModalWindow */ 
  611.     {
  612.         if (gTheModalWindow)
  613.           return (gTheModalWindow->Do (theEvent));
  614.     }
  615.     
  616. /*-----------------------------------------------------------------*/
  617.  
  618.     void    CPPWindow::Activate (void)
  619.     /* do the necessary bookkeeping to keep track of the window's state */
  620.     /* and pass the message on to all the window's contents */
  621.     {        
  622.         for (long i = 1; i<= GetNumItems(); i++)
  623.           {
  624.               CPPVisualObject    *theObject = (CPPVisualObject *)((*this)[i]);
  625.               if (theObject)
  626.                 theObject->Activate(TRUE);
  627.           }
  628.           
  629.         if (this->theWindow)
  630.           this->WisActive = TRUE;
  631.     }
  632.             
  633. /*-----------------------------------------------------------------*/
  634.  
  635.     void    CPPWindow::Deactivate (void)
  636.     /* do the necessary bookkeeping to keep track of the window's state */
  637.     {
  638.         for (long i = 1; i<= GetNumItems(); i++)
  639.           {
  640.               CPPVisualObject    *theObject = (CPPVisualObject *)((*this)[i]);
  641.               if (theObject)
  642.                 theObject->Activate(FALSE);
  643.           }
  644.  
  645.         if (this->theWindow)
  646.             this->WisActive = FALSE;
  647.     }
  648.  
  649. /*-----------------------------------------------------------------*/
  650.  
  651.     void    CPPWindow::DoUserChangeSize (short newWidth, short newHeight)
  652.     /* instance specific handler for changing the size of the window */
  653.     /* You might use this to move the window's scrollbars, if it has */
  654.     /* any */
  655.     /* SUBCLASS SHOULD OVERRIDE */
  656.     {
  657.     
  658.     }
  659.  
  660. /*-----------------------------------------------------------------*/
  661.  
  662.     void    CPPWindow::DoUserClick (EventRecord *theEvent)
  663.     /* instance specific handler for clicking in the window */
  664.     /* this handler tests each item and passes the click to the */
  665.     /* one where it occurred */
  666.     /* SUBCLASS SHOULD OVERRIDE */
  667.     {
  668.         for (long i = 1; i<= GetNumItems(); i++)
  669.           {
  670.               CPPVisualObject *theObject = (CPPVisualObject *)((*this)[i]);
  671.               if (theObject && theObject->InContent(theEvent->where))
  672.                 {
  673.                     MakeTarget(theObject);
  674.                   if (theObject->DoClick(theEvent))
  675.                     break;
  676.                 }
  677.           }
  678.     }
  679.     
  680. /*-----------------------------------------------------------------*/
  681.  
  682.     void    CPPWindow::DoUserUpdate (void)
  683.     /* instance specific handler for drawing the window's contents */
  684.     /* this handler goes through each item and draws it */
  685.     /* SUBCLASS SHOULD OVERRIDE */
  686.     {
  687.         for (long i = 1; i<= GetNumItems(); i++)
  688.           {
  689.               CPPVisualObject *theObject = (CPPVisualObject *)((*this)[i]);
  690.               if (theObject)
  691.                 theObject->Draw();
  692.           }
  693.     }
  694.  
  695. /*-----------------------------------------------------------------*/
  696.  
  697.     void    CPPWindow::DoUserIdle (void)
  698.     /* instance specific handler for idling when the window is */
  699.     /* the frontmost window - hand it to the current target object */
  700.     /* SUBCLASS SHOULD OVERRIDE */
  701.     {
  702.         if (currentTarget)
  703.           currentTarget->DoIdle();
  704.     }
  705.  
  706. /*-----------------------------------------------------------------*/
  707.  
  708.     Boolean    CPPWindow::DoUserKey (EventRecord *theEvent)
  709.     /* instance specific handler for handling a keypress - hand */
  710.     /* it off to the current target object. */
  711.     /* return TRUE if we handled the key, FALSE otherwise */
  712.     /* SUBCLASS SHOULD OVERRIDE */
  713.     {
  714.         if (currentTarget)
  715.           return currentTarget->DoKey(theEvent->message & charCodeMask,
  716.                                         theEvent->modifiers, theEvent->what);
  717.         else
  718.           return FALSE;
  719.     }
  720.  
  721. /*-----------------------------------------------------------------*/
  722. /*----------------------- PRIVATE METHODS -------------------------*/
  723. /*-----------------------------------------------------------------*/
  724.  
  725.     void    CPPWindow::DoDragClick (EventRecord *theEvent)
  726.     /* drag a window around the screen */
  727.     {
  728.         RgnHandle    deskRegion = GetGrayRgn();
  729.         
  730.         if (this->theWindow)
  731.           DragWindow(this->theWindow, theEvent->where, 
  732.                        &((**deskRegion).rgnBBox));
  733.     }
  734.             
  735. /*-----------------------------------------------------------------*/
  736.  
  737.     void    CPPWindow::DoZoomClick (EventRecord *theEvent, short thePart)
  738.     {
  739.         Point    myPt;
  740.         Rect    tempRect;
  741.         
  742.         if (this->theWindow)
  743.           {
  744.               SetPort(this->theWindow);
  745.               myPt = theEvent->where;
  746.               GlobalToLocal(&myPt);
  747.               if (TrackBox(this->theWindow, myPt, thePart))
  748.                 {
  749.                     ZoomWindow (this->theWindow, thePart, TRUE);
  750.                     
  751.                     // erase the contents of the window
  752.                     SetRect (&tempRect, 0, 0, 32000, 32000);
  753.                     EraseRect(&tempRect);
  754.                     InvalRect(&tempRect);
  755.                     
  756.                     // let the user know the window changed size
  757.                     tempRect = this->theWindow->portRect;
  758.                     DoUserChangeSize (tempRect.right - tempRect.left,
  759.                                       tempRect.bottom - tempRect.top);
  760.                     
  761.                 }
  762.           }
  763.     }
  764.         
  765. /*-----------------------------------------------------------------*/
  766.  
  767.     void    CPPWindow::DoGoAwayClick (EventRecord *theEvent)
  768.     {
  769.         if (this->theWindow)
  770.           {
  771.             if (TrackGoAway (this->theWindow, theEvent->where))
  772.               this->Close();
  773.           }
  774.     }
  775.             
  776. /*-----------------------------------------------------------------*/
  777.  
  778.     void    CPPWindow::DoGrowClick (EventRecord *theEvent)
  779.     {
  780.         Point    myPt;
  781.         Rect    tempRect, oldRect;
  782.         long    mResult;
  783.         WStateData    **hWSD;
  784.         
  785.         if (this->theWindow)
  786.           {
  787.               SetPort(this->theWindow);
  788.               myPt = theEvent->where;
  789.               GlobalToLocal(&myPt);
  790.  
  791.             oldRect = this->theWindow->portRect;
  792.  
  793.             // Set the minimum and maximum sizes for the drag
  794.               SetRect (&tempRect, this->minWidth, this->minHeight,
  795.                         this->maxWidth, this->maxHeight);
  796.                         
  797.               // Drag, then change the window size
  798.               mResult = GrowWindow (this->theWindow, theEvent->where, &tempRect);
  799.               SizeWindow (this->theWindow, LoWord(mResult), 
  800.                           HiWord(mResult), TRUE);
  801.               
  802.               // erase the contents of the window
  803.               SetRect (&tempRect, 0, 0, 32000, 32000);
  804.               EraseRect (&tempRect);
  805.               InvalRect (&tempRect);
  806.  
  807.                 //let the user know the window changed size
  808.                 tempRect = this->theWindow->portRect;
  809.                 DoUserChangeSize (tempRect.right - tempRect.left,
  810.                                   tempRect.bottom - tempRect.top);
  811.           }
  812.     }
  813.             
  814. /*-----------------------------------------------------------------*/
  815.  
  816.     void    CPPWindow::DoContentClick (EventRecord *theEvent)
  817.     {
  818.         if (this->theWindow)
  819.           {
  820.               if (!this->WisActive)
  821.                 this->ourManager->ActivateWindowObject(this);
  822.               SetPort(this->theWindow);
  823.               this->DoUserClick (theEvent);
  824.           }
  825.     }
  826.             
  827. /*-----------------------------------------------------------------*/
  828. /*----------------------- PRIVATE METHODS -------------------------*/
  829. /*-----------------------------------------------------------------*/
  830.  
  831.     void    CPPWindow::MakeCPPWindow (CPPWindowManager *theManager,
  832.                                       short windowFont, short windowSize)
  833.     /* the common part of both constructors */
  834.     {
  835.         GrafPtr    savePort;
  836.         
  837.         this->minWidth = 70;
  838.         this->minHeight = 70;
  839.         
  840.         this->currentTarget = NULL;
  841.         // remember which window manager is ours, and add ourself to 
  842.         // its list
  843.         this->ourManager = theManager;
  844.           this->ourManager->DeactivateWindowObject(this->ourManager->FrontWindowObject());
  845.         this->ourManager->StartManagingWindow(this);
  846.           this->WisActive = FALSE;
  847.           this->WisVisible = ((WindowPeek)this->theWindow)->visible;
  848.           this->ourManager->ActivateWindowObject(this);
  849.           SelectWindow (this->theWindow);
  850.           
  851.           // set the font and font size for the window
  852.           GetPort (&savePort);
  853.           SetPort (this->theWindow);
  854.           TextFont (windowFont);
  855.           TextSize (windowSize);
  856.           SetPort (savePort);
  857.           
  858.     }
  859.